package com.cslc.wechat.common.dao;

import java.util.Collection;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.springframework.transaction.annotation.Transactional;

public interface BaseDAO {

	/**
	 * 删除一条记录
	 * 
	 * @param entity 删除记录对应的对象
	 */
	public void delete(Object entity);

	/**
	 * 根据主键删除记录
	 * 
	 * @param entityClass 删除记录对应的对象类
	 * @param id 删除记录对应的主键
	 * 
	 */
	public <T> void deleteById(Class<T> entityClass, int id);
	public <T> void deleteById(Class<T> entityClass, long id);
	
	/**
	 * 根据主键查询,返回一个对象
	 * 
	 * @param entityClass 要查询对象的类
	 * @param id 对象对应的主键值
	 * 
	 * @return 查询的对象
	 */
	public <T> T findById(Class<T> entityClass, int id);
	public <T> T findById(Class<T> entityClass, long id);

	/**
	 *  查询的where条件会自动加上数据库中所有不能为null的字段。
	 *  如果数据库中数据字段为null，查询的时候不会报错，但是查询不出数据，因为这种查询的条件是数据库中不能为null的所有字段。 
	 * @param entity
	 * @return
	 */
	public <T> List<T> findByExample(Object entity);

	/**
	 * 根据对象进行查询，返回表中的所有值.
	 * 
	 * @param entityClass 对象类
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findAll(Class<T> entityClass);

	/**
	 * 根据对象的属性值进行查询
	 * 
	 * @param entityClass 对象类
	 * @param propertyName  查询的属性名
	 * @param propertyValue 查询属性的值
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findByProperty(Class<T> entityClass, String propertyName,
			String propertyValue);

	/**
	 * 保存一条数据
	 * 
	 * @param entity 保存数据的对象
	 */
	public void save(Object entity);

	/**
	 * 
	 * 更新一条数据
	 * 
	 * @param entity 更新数据的对象
	 */
	public void update(Object entity);
	
	/**
	 * 批量删除对象
	 * 
	 * @param entities 要删除的对象集合
	 */
	@Transactional
	public <T> void deleteAllEntities(Collection<T> entities);

	/**
	 * 批量插入对象集合
	 * 
	 * @param entities
	 */
	public <T> void batchInsert(Collection<T> entities);
	
	/**
	 * 批量插入或更新对象集合
	 * 
	 * @param entities
	 */
	public void batchInsertOrUpdate(Collection entities);
	
	/**
	 * 批量更新持久化对象
	 * 
	 * @param updateString
	 *            String 批量更新的hql语句，可以是update，也可以是delete
	 * @return int 被批量更新的持久化对象数量
	 */
	public int batchUpdate(String updateString);

	/**
	 * 批量更新持久化对象，带参数
	 * 
	 * @param updateString
	 *            String 批量更新的hql语句，可以是update，也可以是delete，带一个参数
	 * @param entity
	 *            Object 参数值
	 * @return int 被批量更新的持久化对象数量
	 */
	public int batchUpdate(String updateString, Object entity);

	/**
	 * 批量更新持久化对象，带参数
	 * 
	 * @param updateString
	 *            String 批量更新的hql语句，可以是update，也可以是delete，带多个参数
	 * @param entities
	 *            Object[] 参数值数组
	 * @return int 被批量更新的持久化对象数量
	 */
	public int batchUpdate(String updateString, Object[] entities);
	
	/**
	 * 根据Critera条件查询
	 * 
	 * @param criteria
	 * @return 查询结果
	 * @author lifengyong
	 * @version 1.00 新建
	 */
	public List findByCriteria(DetachedCriteria criteria);
	
	/**
	 * 根据综合条件查询（可以根据查询条件的构造，查询不同的对象）
	 * 
	 * @param detachedCriteria 构造的查询对象
	 * @param rollPage 分页辅助类
	 * 
	 * @return 需要查询的对象的集合
	 */
	public List findByCriteria(DetachedCriteria detachedCriteria, final int offSet,
			final int pageSize);
	
	/**
	 * 根据构造的综合查询条件查找符合条件的记录的总数
	 * @param detachedCriteria 构造的查询对象
	 * 
	 * @return 符合查询条件的记录总数
	 */
	public int findByCriteriaCounts(DetachedCriteria detachedCriteria);
  
    /** 
	 * 查询所有记录数(HQL)
	 * 
	 * @param hql 查询的语句
	 * 
	 * @return 总记录数
	 */
	public long findCountByHQL(final String hql, final Object[] values); 
	
	/** 
	 * 查询所有记录数(原生SQL)
	 * 
	 * @param sql 查询的语句
	 * @param 参数
	 * 
	 * @return 总记录数
	 */
	public long findCountBySQL(final String sql, final Object[] values);
	
	/** 
	 * 查询所有记录数(原生SQL)
	 * 
	 * @param sql 查询的语句
	 * 
	 * @return 总记录数
	 */
	public int findCountBySQL(String sql);
	
	/**
	 * 使用hql语句进行查询
	 * 
	 * @param hql 需要查询的hql语句
	 * @param values 如果hql有多个个参数需要传入，values就是传入hql的参数数组
	 * 
	 * @return 当前页的所有记录
	 */
	public List findByHQL(final String hql, final Object[] values);
	
	/**
	 * 使用sql语句进行查询
	 * 
	 * @param hql 需要查询的hql语句
	 * @param values 如果hql有多个个参数需要传入，values就是传入hql的参数数组
	 * 
	 * @return 当前页的所有记录
	 */
	public List findBySQL(final String sql, final Object[] values);
	
	/**
	 * 使用sql语句进行查询,返回封装好的对象结果集
	 * 
	 * @param sql
	 * @param entityClass
	 * @param values 如果sql有多个个参数需要传入，values就是传入sql的参数数组
	 * @return 封装好的对象结果集
	 */
	public <T> List<T> findObjectBySql(final String sql, final Class<T> entityClass, final Object[] values);
	
	/**
	 * 使用hql语句进行查询,返回封装好的对象结果集
	 * 
	 * @param hql
	 * @param entityClass
	 * @param values 如果hql有多个个参数需要传入，values就是传入hql的参数数组
	 * @return 封装好的对象结果集
	 */
	public <T> List<T> findObjectByHql(final String hql, final Class<T> entityClass, final Object[] values);
	
	/**
	 * 执行hql语句
	 * 
	 * @param hql 需要执行的hql语句
	 * @param values 如果hql有多个个参数需要传入，values就是传入hql的参数数组
	 * 
	 * @return 执行记录数
	 */
	public int executeByHql(final String hql, final Object[] values);
	
	/**
	 * 执行sql语句
	 * 
	 * @param sql 需要执行的sql语句
	 * @param values 如果sql有多个个参数需要传入，values就是传入sql的参数数组
	 * 
	 * @return 执行记录数
	 */
	public int executeBySql(final String sql, final Object[] values);

	/**
	 * 分页查询：根据对象
	 * 
	 * @param entityClass 对象类
	 * @param offSet 目标页
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findByPage(Class<T> entityClass, final int offSet);

	/**
	 * 分页查询：根据对象。总记录数，用于计算显示多少页
	 * 
	 * @param entityClass 对象类
	 * 
	 * @return 总记录数
	 */
	public <T> Integer getTotalNum(Class<T> entityClass);

	/**
	 * 分页查询：根据自定义hql语句
	 * 
	 * @param hql 拼装的HQL语句
	 * @param offSet 目标页
	 * @param pageSize 每页的记录数
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findByPage(final String hql, final int offSet,
			final int pageSize);
	
	/**
	 * 分页查询：根据HQL语句。总记录数，用于计算显示多少页
	 * 
	 * @param entityClass 对象类
	 * 
	 * @return 总记录数
	 */
	public <T> long getTotalNum(final String hql);

	/**
	 * 分页查询：根据自定义hql语句和单个参数
	 * 
	 * @param hql 拼装的HQL语句
	 * @param param 单个参数
	 * @param offSet 目标页
	 * @param pageSize 每页的记录数
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findByPage(final String hql, final Object param,
			final int offSet, final int pageSize);
	
	/**
	 * 分页查询：根据自定义hql语句和单个参数。总记录数，用于计算显示多少页
	 * 
	 * @param entityClass 拼装的HQL语句
	 * @param param 单个参数
	 * 
	 * @return 总记录数
	 */
	public <T> long getTotalNum(final String hql, final Object param);

	/**
	 * 分页查询：根据自定义hql语句和多个参数
	 * 
	 * @param hql 拼装的HQL语句
	 * @param params 多个参数，以数组形式
	 * @param offSet 目标页
	 * @param pageSize 每页的记录数
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findByPage(final String hql, final Object[] params,
			final int offSet, final int pageSize);
	
	/**
	 * 分页查询：根据自定义hql语句和多个参数。总记录数，用于计算显示多少页
	 * 
	 * @param hql 拼装的HQL语句
	 * @param param 多个参数
	 * 
	 * @return 总记录数
	 */
	public <T> long getTotalNum(final String hql, final Object[] param);
	
	/**
	 * 分页查询：根据自定义hql语句，自定义的DTO对象和多个参数
	 * 
	 * @param hql 拼装的HQL语句
	 * @param params 多个参数，以数组形式
	 * @param offSet 目标页
	 * @param pageSize 每页的记录数
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findObjectByHQLPage(final String hql, final Class<T> entityClass, final Object[] params, 
			final int offSet, final int pageSize);
	
	/**
	 * 分页查询：根据自定义hql语句，自定义的DTO对象和多个参数。总记录数，用于计算显示多少页
	 * 
	 * @param hql 拼装的HQL语句
	 * @param entityClass 拼装的HQL语句
	 * @param param 多个参数
	 * 
	 * @return 总记录数
	 */
	public <T> long findObjectByHQLTotalNum(final String hql, final Class<T> entityClass, final Object[] params);
	
	/**
	 * 分页查询：根据自定义hql语句，自定义的DTO对象和多个参数
	 * 
	 * @param sql 拼装的SQL语句
	 * @param params 多个参数，以数组形式
	 * @param offSet 目标页
	 * @param pageSize 每页的记录数
	 * 
	 * @return 对象列表
	 */
	public <T> List<T> findObjectBySQLPage(final String sql, final Class<T> entityClass, final Object[] params,
			final int offSet, final int pageSize);
	
	/**
	 * 分页查询：根据自定义sql语句，自定义的DTO对象和多个参数。总记录数，用于计算显示多少页
	 * 
	 * @param sql 拼装的SQL语句
	 * @param entityClass 拼装的SQL语句
	 * @param param 多个参数
	 * 
	 * @return 总记录数
	 */
	public <T> long findObjectBySQLTotalNum(final String sql, final Class<T> entityClass, final Object[] params);
	
	/**
	 * 每n条记录进行一次数据持久化并清除缓存
	 * @param newCount 当前记录数
	 * @param n
	 */
	public void flushClearSession(int newCount, int n);
	
	/**
	 * 数据持久化并清除缓存
	 */
	public void flushClearSession();

}
